﻿using System;
using UnityEngine;

namespace UnityTouchTable.Runtime
{
    /// <summary>
    /// Marker项
    /// </summary>
    public class MarkerItemBase : MonoBehaviour, IMarkerItem
    {
        #region Field
        /// <summary>
        /// ID
        /// </summary>
        [SerializeField]
        [Header("Marker ID")]
        [Range(0, 8)]
        protected int m_ID = 0;

        /// <summary>
        /// 深度
        /// 距离相机的深度
        /// 非Ui使用此参数
        /// </summary>
        [SerializeField]
        [Header("深度,距离相机的深度,非Ui使用此参数")]
        [Min(0.1f)]
        protected float m_WorldDepth = 10.0f;

        /// <summary>
        /// 是否平滑插值中心位置
        /// </summary>
        [SerializeField]
        [Header("是否平滑插值中心位置")]
        protected bool m_LerpCenterPosition = true;

        /// <summary>
        /// 移动速度
        /// </summary>
        [SerializeField]
        [Header("移动速度")]
        [Min(0.1f)]
        protected float m_MoveSpeed = 1.0f;

        /// <summary>
        /// 是否是UI
        /// </summary>
        protected bool m_IsUI;

        /// <summary>
        /// RectTransform
        /// </summary>
        protected RectTransform m_RectTransform;

        /// <summary>
        /// 角度处理器
        /// </summary>
        [SerializeField]
        [Header("角度处理器")]
        protected IAnglehandle[] m_Anglehandles;

        /// <summary>
        /// 上次位置
        /// </summary>
        private Vector3 m_LastCenterPosition = Vector3.zero;

        /// <summary>
        /// 目标位置
        /// </summary>
        private Vector3 m_TargetCenterPosition = Vector3.zero;
        #endregion

        #region Property
        /// <summary>
        /// Marker项ID
        /// </summary>
        public virtual int MarkerItemID => this.m_ID;
        #endregion

        private void OnEnable()
        {
            //UnityTouchTableEntry unityTouchTableEntry = GameObject.FindObjectOfType<UnityTouchTableEntry>();
            //if (unityTouchTableEntry == null)
            //    return;

            //unityTouchTableEntry.AddMarkerItem(this);
            this.m_Anglehandles = this.GetComponentsInChildren<IAnglehandle>();
        }

        private void Update()
        {
            if (!this.m_LerpCenterPosition)
                return;

            if (this.m_IsUI)
            {
                Vector2 targetCenterPosition = new Vector2(this.m_TargetCenterPosition.x, this.m_TargetCenterPosition.y);
                if ((this.m_RectTransform.anchoredPosition - targetCenterPosition).sqrMagnitude < 0.1f)
                    return;

                this.m_RectTransform.anchoredPosition = Vector2.Lerp(this.m_RectTransform.anchoredPosition, targetCenterPosition, Time.deltaTime * this.m_MoveSpeed);
            }
            else
            {
                if ((this.transform.localPosition - this.m_TargetCenterPosition).sqrMagnitude < 0.1f)
                    return;

                this.transform.localPosition = Vector3.Lerp(this.transform.localPosition, this.m_TargetCenterPosition, Time.deltaTime * this.m_MoveSpeed);
            }
        }

        private void OnDisable()
        {
            //UnityTouchTableEntry unityTouchTableEntry = GameObject.FindObjectOfType<UnityTouchTableEntry>();
            //if (unityTouchTableEntry == null)
            //    return;

            //unityTouchTableEntry.RemoveMarkerItem(this.m_ID);
            Array.Clear(this.m_Anglehandles, 0, this.m_Anglehandles.Length);
            this.m_Anglehandles = null;
        }

        #region Function
        /// <summary>
        /// 初始化
        /// </summary>
        public virtual void Init()
        {
            if (!(this.transform is RectTransform))
            {
                this.m_IsUI = false;
                return;
            }

            this.m_IsUI = true;
            this.m_RectTransform = this.transform as RectTransform;
            this.m_RectTransform.anchorMin = Vector2.zero;
            this.m_RectTransform.anchorMax = Vector2.zero;
            this.gameObject.SetActive(false);
        }

        /// <summary>
        /// 添加Marker
        /// </summary>
        /// <param name="centerPosition">中心位置</param>
        /// <param name="initAngle">初始角度</param>
        public virtual void AddMarker(Vector2 centerPosition, float initAngle)
        {
            //UI
            if (this.m_IsUI)
            {
                if (this.m_LerpCenterPosition)
                    this.m_TargetCenterPosition = new Vector3(centerPosition.x, centerPosition.y, 0.0f);
                else
                    this.m_RectTransform.anchoredPosition = centerPosition;

                this.m_LastCenterPosition = new Vector3(centerPosition.x, centerPosition.y, 0.0f);
                //this.m_RectTransform.eulerAngles = Vector3.zero;
            }
            //World
            else
            {
                Camera main = Camera.main;
                if (main == null)
                    return;

                Vector3 currentCenterPosition = main.ScreenToWorldPoint(new Vector3(centerPosition.x, centerPosition.y, this.m_WorldDepth));

                if (this.m_LerpCenterPosition)
                    this.m_TargetCenterPosition = currentCenterPosition;
                else
                    this.transform.localPosition = currentCenterPosition;

                this.m_LastCenterPosition = currentCenterPosition;
                //this.transform.eulerAngles = Vector3.zero;
            }

            this.gameObject.SetActive(true);
        }

        /// <summary>
        /// 更新Marker
        /// </summary>
        /// <param name="centerPosition">中心位置</param>
        /// <param name="initAngle">初始角度</param>
        /// <param name="currentAngle">当前角度</param>
        /// <param name="relativeAngle">相对角度</param>
        public virtual void UpdateMarker(Vector2 centerPosition, float initAngle, float currentAngle, float relativeAngle)
        {
            bool move = false;

            //UI
            if (this.m_IsUI)
            {
                if (this.m_LerpCenterPosition)
                    this.m_TargetCenterPosition = new Vector3(centerPosition.x, centerPosition.y, 0.0f);
                else
                    this.m_RectTransform.anchoredPosition = centerPosition;

                move = (centerPosition - new Vector2(this.m_LastCenterPosition.x, this.m_LastCenterPosition.y)).sqrMagnitude > 30.0f;
                this.m_LastCenterPosition = new Vector3(centerPosition.x, centerPosition.y, 0.0f);
                //this.m_RectTransform.eulerAngles = Vector3.forward * relativeAngle;
            }
            //World
            else
            {
                Camera main = Camera.main;
                if (main == null)
                    return;

                Vector3 currentCenterPosition = main.ScreenToWorldPoint(new Vector3(centerPosition.x, centerPosition.y, this.m_WorldDepth));

                if (this.m_LerpCenterPosition)
                    this.m_TargetCenterPosition = currentCenterPosition;
                else
                    this.transform.localPosition = currentCenterPosition;

                move = (new Vector3(currentCenterPosition.x, currentCenterPosition.y, 0.0f) - this.m_LastCenterPosition).sqrMagnitude > 30.0f;
                this.m_LastCenterPosition = new Vector3(currentCenterPosition.x, currentCenterPosition.y, 0.0f);
                //this.transform.eulerAngles = Vector3.forward * relativeAngle;
            }

            for (int i = 0; i < this.m_Anglehandles.Length; i++)
            {
                IAnglehandle anglehandle = this.m_Anglehandles[i];
                if (anglehandle.OnMoveUpdateAngle)
                    anglehandle.UpdateAngle(relativeAngle);
                else
                {
                    if (!move)
                        anglehandle.UpdateAngle(relativeAngle);
                }
            }
        }

        /// <summary>
        /// 移除Marker
        /// </summary>
        public virtual void RemoveMarker()
        {
            //UI
            if (this.m_IsUI)
            {
                this.m_RectTransform.anchoredPosition = Vector2.zero;
                //this.m_RectTransform.eulerAngles = Vector3.zero;
            }
            //World
            else
            {
                this.transform.localPosition = Vector3.zero;
                //this.transform.eulerAngles = Vector3.zero;
            }

            this.m_LastCenterPosition = Vector3.zero;
            this.gameObject.SetActive(false);
        }
        #endregion
    }
}